home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ddj0290.arc / PATERSON.LST < prev    next >
File List  |  1990-01-07  |  7KB  |  311 lines

  1. _MANAGING MULTIPLE DATA SEGMENTS UNDER MICROSOFT WINDOWS: PART I_
  2. by Tim Paterson and Steve Flenniken
  3.  
  4. [LISTING ONE]
  5.  
  6.     page 78,132
  7.     .xlist
  8.     include    CMACROS.INC
  9.     .list
  10. ?PLM    =    0            ;Use C calling convention
  11.  
  12.     .model    medium
  13.     .code
  14.  
  15. cProc    memcpyifp,<PUBLIC>,<ds,si,di>
  16. parmD    DestIfp
  17. parmD    SourceIfp
  18. parmW    cb
  19. cBegin
  20.     mov    bx,SEG_DestIfp
  21.     mov    dx,bx            ;pSeg is high word of return value
  22.     mov    es,ds:[bx]        ;Segment of destination
  23.     mov    bx,SEG_SourceIfp
  24.     mov    ds,ds:[bx]        ;Segment of source
  25.     mov    si,OFF_SourceIfp
  26.     mov    di,OFF_DestIfp
  27.     mov    ax,di            ;Low word of return value
  28.     mov    cx,cb
  29. ;Source in ds:si
  30. ;Destination in es:di
  31. ;Count in cx
  32.     shr    cx,1            ;Move by words
  33. rep    movsw
  34.     jnc    EvenBytes        ;Was it an even number?
  35.     movsb                ;Move the odd byte
  36. EvenBytes:
  37.  
  38. ;return value is destination IFP in dx:ax
  39.  
  40. cEnd
  41.     end
  42.  
  43.  
  44. [LISTING TWO]
  45.  
  46. /* segtable.c */
  47.  
  48. #include "windows.h"
  49. #define GLOBAL
  50. #include "segtable.h"
  51.  
  52. static PSEG NEAR freelist;
  53.  
  54. void FAR PASCAL SegmentInit(void)
  55. {
  56.     freelist = 0;
  57.     cwSegs = MINPSEGS;
  58.     DefineHandleTable(SegmentTable);
  59.     segDgroup = HIWORD((void FAR *)&segDgroup);
  60. }
  61.  
  62. PSEG FAR PASCAL SegmentAlloc(DWORD size)
  63. {
  64.     PSEG    pseg;
  65.     HANDLE    handle;
  66.  
  67.     if (freelist)
  68.     {
  69.         if (!(handle = GlobalAlloc(GMEM_MOVEABLE, size)))
  70.             return((PSEG)0);
  71.  
  72.         pseg = freelist;
  73.         freelist = (PSEG)*freelist;
  74.     }
  75.     else
  76.     {
  77.         if (cwSegs >= MAXPSEGS)
  78.             return((PSEG)0);
  79.  
  80.         if (!(handle = GlobalAlloc(GMEM_MOVEABLE, size)))
  81.             return((PSEG)0);
  82.  
  83.         pseg = &SegmentTable[cwSegs+2];
  84.         cwSegs++;
  85.     }
  86.     *pseg = GlobalSegment(handle);
  87.     return(pseg);
  88. }
  89.  
  90. void FAR PASCAL SegmentFree(PSEG pseg)
  91. {
  92. #if DEBUG
  93.     if (!VALID_VARIABLE_PSEG(pseg))
  94.         SegmentError();
  95. #endif
  96.     if (*pseg)
  97.     {
  98. #if DEBUG
  99.         if ((*pseg % 2) == 0)
  100.             SegmentError();
  101. #endif
  102.         GlobalFree((HANDLE)GlobalHandle(*pseg));
  103.     }
  104.     *(PSEG *)pseg = freelist;
  105.     freelist = pseg;
  106. }
  107.  
  108. void FAR PASCAL DataFree(PSEG pseg)
  109. {
  110. #if DEBUG
  111.     if (!VALIDPSEG(pseg) || (*pseg % 2) == 0)
  112.         SegmentError();
  113. #endif
  114.     GlobalFree((HANDLE)GlobalHandle(*pseg));
  115.     *pseg = 0;
  116. }
  117.  
  118. BOOL FAR PASCAL SegmentRealloc(PSEG pseg, DWORD size)
  119. {
  120.     HANDLE    handle;
  121.  
  122. #if DEBUG
  123.     if (!VALIDPSEG(pseg))
  124.         SegmentError();
  125. #endif
  126.     if (*pseg)
  127.     {
  128. #if DEBUG
  129.         if ((*pseg % 2) == 0)
  130.             SegmentError();
  131. #endif
  132.         return ( (BOOL) GlobalReAlloc( (HANDLE)GlobalHandle(*pseg), size, 
  133.                 GMEM_MOVEABLE));
  134.     }
  135.     else
  136.     {
  137.         if (!(handle = GlobalAlloc(GMEM_MOVEABLE, size)))
  138.             return(FALSE);
  139.  
  140.         *pseg = GlobalSegment(handle);
  141.         return(TRUE);
  142.     }
  143. }
  144.  
  145. #if DEBUG
  146. void FAR PASCAL SegmentError(void)
  147. {
  148.     FatalExit(-1);
  149. }
  150. #endif
  151.  
  152. [LISTING THREE]
  153.  
  154.  
  155. /* segtable.h */
  156.  
  157. #define MAXPSEGS    9
  158. #define MINPSEGS    1
  159.  
  160. #define cwSegs SegmentTable[0]
  161. #define cwClear SegmentTable[1]
  162. #define segDgroup SegmentTable[2]
  163.  
  164. #ifndef GLOBAL
  165. #define GLOBAL extern
  166. #endif
  167.  
  168. typedef WORD BOOLEAN;
  169. typedef WORD SEG;
  170. typedef SEG NEAR *PSEG;
  171. typedef unsigned long IFP;
  172.  
  173. #define FARPTR(off, seg) ( (void FAR *)MAKELONG(off, seg) )
  174. #define MAKEIFP(off,pseg) ( (IFP)MAKELONG(off, pseg) )
  175. #define IFP2SEG(ifp)        ( *(PSEG)HIWORD(ifp) )
  176. #define IFP2PTR(ifp)     FARPTR(LOWORD(ifp), IFP2SEG(ifp))
  177.  
  178. #define GlobalSegment(handle) ((SEG) HIWORD(GlobalHandle(handle)) )
  179.  
  180. void FAR PASCAL SegmentInit(void);
  181. PSEG FAR PASCAL SegmentAlloc(DWORD size);
  182. void FAR PASCAL SegmentFree(PSEG pseg);
  183. void FAR PASCAL DataFree(PSEG pseg);
  184. BOOL FAR PASCAL SegmentRealloc(PSEG pseg, DWORD size);
  185. void FAR PASCAL DefineHandleTable(WORD NEAR *segtable);
  186. void FAR PASCAL SegmentError(void);
  187.  
  188. GLOBAL SEG NEAR SegmentTable[MAXPSEGS + 2];
  189.  
  190. #define VALIDPSEG(pseg) \
  191.         (pseg > &SegmentTable[1] && \
  192.          pseg < &SegmentTable[MAXPSEGS + 2] && \
  193.          ((WORD)pseg % 2) == 0)
  194.  
  195. #define VALID_VARIABLE_PSEG(pseg) \
  196.         (pseg > &SegmentTable[MINPSEGS + 1] && \
  197.          pseg < &SegmentTable[MAXPSEGS + 2] && \
  198.          ((WORD)pseg % 2) == 0)
  199.  
  200.  
  201.  
  202. Examplσ 1║ Samplσ sourcσ codσ fo≥ settinτ asidσ the segment table
  203.  
  204. /¬ WOR─ defineΣ a≤ unsigneΣ shor⌠ iε windows.Φ */
  205. #definσ MAXPSEG╙ 3░  /¬ ma° ú oµ tablσ segment≤ */
  206. WOR─ SegmentTable[MAXPSEGS+2];
  207. #definσ cwSeg≤  SegmentTable[0]
  208. #definσ cwClea≥ SegmentTable[1]
  209.  
  210.  
  211. Examplσ 2║  Sample code for puttting the group into the table
  212.  
  213. #define segDgroup    SegmentTable[2]
  214. segDgroup = HIWORD((void FAR *)&SegDgroup);
  215. ++cwSegs;  /* was zero, now 1 */
  216.  
  217.  
  218. Examplσ 3║ GlobalHandle() converts a handle to a segment
  219.  
  220. if ( hMem = GlobalAlloc(flags, dwBytes) )
  221.    SegmentTable[i] = HIWORD( GlobalHandle(hMem) );
  222. else
  223.    /* out of memory */
  224.  
  225.  
  226. Examplσ 4║ Macro fo≥ creating a file pointer
  227.  
  228. #define FARPTR(off,seg)    ((void FAR*)MAKELONG(off,seg))
  229. *(WORD FAR *) FARPTR(0,segSheetDescr) = 0; 
  230.  
  231. Examplσ 5║ Macro fo≥ referencinτ ß particula≥ type
  232.  
  233.  
  234. #define FARWORD(off,seg) (*(WORD FAR*)FARPTR(off,seg))
  235. FARWORD(0,segSheetDescr) = 0;    /* no sheets loaded */
  236.  
  237.  
  238. Examplσ 6║ Buildinτ iε ß segment
  239.  
  240. #define FARDESCR(off) (*(DESCR FAR*)FARPTR (off,segSheetDescr))
  241. typedef struct  /* descriptor for a spreadsheet */
  242. {
  243.     unsigned short    SheetId;
  244.     char         *SheetName;
  245.     ...
  246. } DESCR;
  247.  
  248. FARDESCR(pCurSheet).SheetId = NextSheetNum++;
  249. pCurSheetName = FARDESCR(pCurSheet).SheetName;
  250.  
  251. Examplσ 7║ Allocating a segment
  252.  
  253. if ( hMem = GlobalAlloc(flags, dwBytes) )
  254. {
  255.    pSeg = &SegmentTable[++cwSegs + 1];
  256.    *pSeg = HIWORD( GlobalHandle(hMem) );
  257. }
  258. else
  259.    /* out of memory */
  260.  
  261. Examplσ 8║ Defininτ ß ne≈ datß type
  262.  
  263. typedef unsigned long IFP;
  264. #define MAKEIFP(off,pseg) ((IFP)MAKELONG(off,pseg))
  265. #define IFP2SEG(ifp⌐ ( *(WORD NEAR *)HIWORD(ifp))
  266. #define IFP2PTR(ifp⌐ FARPTR(LOWORD(ifp),IFP2SEG(ifp))
  267.  
  268.  
  269. Examplσ ╣║ ┴ cal∞ t∩ ß general-purposσ blocδ cop∙ routine
  270.  
  271. IFP memcpyifp( 
  272.   MAKEIFP(&CurSheetBuf,&segDgroup), /* destination */
  273.   MAKEIFP(pCurSheet,&segSheetDescr)¼ /* source */
  274.   sizeof(DESCR⌐ /* bytes to copy */
  275.  );
  276.  
  277. Examplσ 10║ Onσ wa∙ t∩ codσ memcpyifp()
  278.  
  279. IFP memcpyifp(IFP DestIfp, IFP SourceIfp, unsigned cb)
  280. {
  281.     unsigned i;
  282.     for (i=0; i<cb; i++)
  283.         ((char FAR *)IFP2PTR(DestIfp))[i] =
  284.           ((char FAR *)IFP2PTR(SourceIfp))[i];
  285.     return(DestIfp);
  286. }
  287.  
  288. Examplσ 11║ Storinτ pointer≤ iε loca∞ variables
  289.  
  290.     char FAR *Dest;
  291.     char FAR *Source;
  292.  
  293.     Dest = IFP2PTR(DestIfp);
  294.     Source = IFP2PTR(SourceIfp);
  295.     for (i=0; i<cb; i++)
  296.         Dest[i] = Source[i];
  297.  
  298.  
  299. Examplσ 12║ Writinτ memcpyifp(⌐ usinτ a standard library function
  300.  
  301. IFP memcpyifp(IFP DestIfp, IFP SourceIfp, unsigned cb)
  302. {
  303.    movedata( IFP2SEG(SourceIfp)¼ /* source seg */
  304.    LOWORD(SourceIfp),     /* source offset */
  305.    IFP2SEG(DestIfp),     /* destination seg */
  306.    LOWORD(DestIfp),     /* destination offset */
  307.    cb             /* count of bytes */
  308.   );
  309.  return(DestIfp);
  310. }
  311.